﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace Core.Logger
{
    /// <summary>
    /// Logger implementation. It keeps all the logs into memory and doesn't save them.
    /// This is a singleton implementation.
    /// </summary>
    internal sealed class LoggerMemory : ILogger
    {
        private static readonly LoggerMemory _instance = new LoggerMemory();
        private readonly List<LogItem> _items = new List<LogItem>();

        public event EventHandler<AfterAppendEventArgs> AfterAppend;
        public event EventHandler AfterClear;


        public static LoggerMemory Instance
        {
            get { return _instance; }
        }

        public void Append(string message, params object[] args)
        {
            this.Append(new LogItem
                            {
                                Message = String.Format(message, args),
                                Status = LogStatus.Info
                            });
        }
        public void Append(LogStatus status, string message, params object[] args)
        {
            this.Append(new LogItem 
                { Message = String.Format(message, args), 
                Status = status});
        }
        public void Append(LogItem logItem)
        {
            this._items.Add(logItem);
            OnAfterAppend(new AfterAppendEventArgs(logItem));
       }  
        private void OnAfterAppend(AfterAppendEventArgs e)
        {
            // thread safe
            var temp = AfterAppend;
            if (temp != null)
            {
                temp(this, e);
            }
        }

        public List<LogItem> GetLogs()
        {
            return this._items;
        }
        public List<string> GetErrors()
        {
            return 
                (from logItem in this._items
                 where logItem.Status == LogStatus.Error
                 select logItem.Message).ToList();
        }
        public List<string> GetWarnings()
        {
            return (from logItem in _items
             where logItem.Status == LogStatus.Warning
             select logItem.Message).ToList();
        }

        public void Clear()
        {
            this._items.Clear();
            OnAfterClear();
        }
        private void OnAfterClear()
        {
            var temp = AfterClear;
            if (temp != null)
            {
                temp(this, null);
            }
        }
    }
}
